package me.dwk.dandan.function.functions;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;
import me.dwk.dandan.function.AbstractFunction;
import me.dwk.dandan.function.CompoundVariable;
import me.dwk.dandan.function.ThreadVariables;
import me.dwk.dandan.function.exception.InvalidVariableException;

/**
 * Function to evaluate a string which may contain variable or function
 * references.
 *
 * Parameter: string to be evaluated
 *
 * Returns: the evaluated value
 *
 * @since 2.3.1
 */
@Slf4j
public class EvalVarFunction extends AbstractFunction {

	private static final List<String>	desc				= new LinkedList<>();

	private static final String			KEY					= "__evalVar";			//$NON-NLS-1$

	// Number of parameters expected - used to reject invalid calls
	private static final int			MIN_PARAMETER_COUNT	= 1;
	private static final int			MAX_PARAMETER_COUNT	= 1;

	static {
		desc.add("Name of variable"); //$NON-NLS-1$
	}

	private Object[] values;

	public EvalVarFunction() {}

	/** {@inheritDoc} */
	@Override
	public String execute() throws InvalidVariableException {
		String variableName = ((CompoundVariable) values[0]).execute();
		final ThreadVariables vars = getVariables();
		if (vars == null) {
			log.error("Variables have not yet been defined");
			return "**ERROR - see log file**";
		}
		String variableValue = vars.get(variableName);
		CompoundVariable cv = new CompoundVariable(variableValue);
		return cv.execute();
	}

	/** {@inheritDoc} */
	@Override
	public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
		checkParameterCount(parameters, MIN_PARAMETER_COUNT, MAX_PARAMETER_COUNT);
		values = parameters.toArray();
	}

	/** {@inheritDoc} */
	@Override
	public String getReferenceKey() {
		return KEY;
	}

	/** {@inheritDoc} */
	@Override
	public List<String> getArgumentDesc() {
		return desc;
	}

}
